﻿#include "CIULog.h"
#include "stdarg.h"

#include <QDir>
#include <QDateTime>
#include <QDebug>
#include <QThread>

//日志正文缓冲区长度
#define BUFFER_LENGTH 8196

bool CIULog::m_bToFile = false;
QString CIULog::m_strLogFileName;
QFile CIULog::m_logFile;
LOG_LEVEL CIULog::m_sLogLevel = LOG_LEVEL_INFO;

void CIULog::SetLevel(LOG_LEVEL nLevel)
{
    m_sLogLevel = nLevel;
}

//初始化日志模块
bool CIULog::Init(bool bToFile, QString strLogFileName)
{
    m_bToFile = bToFile;
    m_strLogFileName = strLogFileName;
    if(m_logFile.isOpen())
    {
        m_logFile.close();
    }

    if(m_strLogFileName.isEmpty())
        return false;

    QString strLogDirectory = QDir::currentPath() + "/" + "Log/";

    //检查存放日志文件目录是否存在
    QDir dir;
    dir.setPath(strLogDirectory);
    if(!dir.exists())
    {
        dir.mkdir(strLogDirectory);
    }

    //创建日志文件
    m_logFile.setFileName(m_strLogFileName);
    if(!m_logFile.open(QFile::ReadWrite))
    {
        qDebug() << m_logFile.errorString();
        return false;
    }

    return true;
}

//卸载日志模块
void CIULog::Unit()
{
    if(m_logFile.isOpen())
    {
        m_logFile.close();
    }
}

bool CIULog::Log(long nLevel, const char *pszFmt, ...)
{
    if (nLevel < m_sLogLevel)
            return false;
    //时间
    QString strDebugInfo = QDateTime::currentDateTime().toString("[yyyy-MM-dd hh:mm:ss:zzz] ");

    //错误级别
    QString strLevel("[INFO] ");
    if(nLevel == LOG_LEVEL_WARNING)
        strLevel = "[Warning] ";
    else if(nLevel == LOG_LEVEL_ERROR)
        strLevel ="[Error] ";

    strDebugInfo += strLevel;

    //log正文
    char buf[BUFFER_LENGTH] = {0};
    va_list argList;
    va_start( argList, pszFmt );                             //使用可变的参数链表
    //_vsnprintf( buf, BUFFER_LENGTH, pszFmt, argList );       //将需要打印的信息放入到buf中
    _vsnprintf( buf, BUFFER_LENGTH, pszFmt, argList );
    va_end( argList );

    QString fstr( buf );

    strDebugInfo += fstr;
    strDebugInfo += "\r\n";

    if(m_bToFile)
    {
        if(!m_logFile.isOpen())
            return false;
        std::string str = strDebugInfo.toStdString();
        m_logFile.write(str.c_str(),str.length());
        return true;
    }

    qDebug() << strDebugInfo;

    return true;
}

bool CIULog::Log(long nLevel, const char *FunctionSig, int nLineNo, const char *pszFmt, ...)
{
    if (nLevel < m_sLogLevel)
            return false;
    //时间
    QString strDebugInfo = QDateTime::currentDateTime().toString("[yyyy-MM-dd hh:mm:ss:zzz] ");

    //错误级别
    QString strLevel("[INFO] ");
    if(nLevel == LOG_LEVEL_WARNING)
        strLevel = "[Warning] ";
    else if(nLevel == LOG_LEVEL_ERROR)
        strLevel ="[Error] ";

    strDebugInfo += strLevel;
    //当前线程信息
    uint32_t utThreadID = (uint32_t)QThread::currentThreadId();
    char bufThreadID[32] = {0};
    snprintf( bufThreadID, 32, "[ThreadID:%u] ", utThreadID );
    QString strThreadInfo(bufThreadID);
    strDebugInfo += strThreadInfo;

    //函数签名
    QString funSig = QString("[%1] ").arg(FunctionSig);
    strDebugInfo += funSig;

    //行号
    QString strLineSig = QString("[Line:%1] ").arg(nLineNo);
    strDebugInfo += strLineSig;

    //log正文
    char buf[BUFFER_LENGTH] = {0};
    va_list argList;
    va_start( argList, pszFmt );                             //使用可变的参数链表
    //_vsnprintf( buf, BUFFER_LENGTH, pszFmt, argList );       //将需要打印的信息放入到buf中
    _vsnprintf( buf, BUFFER_LENGTH, pszFmt, argList );
    va_end( argList );

    QString fstr( buf );

    strDebugInfo += fstr;
    strDebugInfo += "\r\n";

    if(m_bToFile)
    {
        if(!m_logFile.isOpen())
            return false;
        std::string str = strDebugInfo.toStdString();
        m_logFile.write(str.c_str(),str.length());
        return true;
    }

    qDebug() << strDebugInfo;
    return true;
}
